using System;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;

using Crainiate.Data.Persistence.Cache;

namespace Crainiate.Data.Persistence
{
    [Serializable]
	public class Order: Column, ISort
	{
		//Property variables
        private SortDirection _direction;

        //Constructors
		public Order(Type type, string field): base(type, field)
		{
			Direction = SortDirection.Ascending;
		}

		public Order(Type type, string field, SortDirection order): base(type, field)
		{
			Direction = order;
		}

        public Order(PropertyInfo field): base(field)
        {
            Direction = SortDirection.Ascending;
        }

        public Order(PropertyInfo field, SortDirection order): base(field)
        {
            Direction = order;
        }

        protected Order(SerializationInfo info, StreamingContext context): base(info, context)
        {
            _direction = (SortDirection) Enum.Parse(typeof(SortDirection), info.GetString("Direction"));
        }

        //Properties
		public virtual SortDirection Direction
		{
			get
			{
				return _direction;
			}
			set
			{
				_direction = value;
			}
		}

        //Methods
        public override int GetHashCode()
        {
            StringBuilder builder = new StringBuilder();

            PropertyInfo prop = PropertyInfo;
            
            if (typeof(IView).IsAssignableFrom(prop.ReflectedType))
            {
                ReflectionCacheItem cache = Component.Instance.ReflectionCache.Lookup(prop.ReflectedType);
                prop = cache.GetOriginalProperty(prop);
            }

            builder.Append(prop.ToString());
            builder.Append(_direction.ToString());

            return builder.ToString().GetHashCode();
        }

        public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            base.GetObjectData(info, context);
            
            info.AddValue("Direction", Convert.ToInt32(Direction).ToString());
        }
	}
}
